lpunbfandomcom-20200214-history
Seminário sobre Python - LP 1/2015 - Grupo 1
Integrantes do grupo 12/0014491 - João Vitor A. Ribeiro 12/0014581 - Jonathan M. de Almeida 12/0021471 - Renato Carlos Pinto 09/0111575 - Eduardo Furtado Sá Corrêa Visão Geral Python é uma linguagem de alto nível, interpretada, multiparadigma, podendo ser funcional, imperativa ou orientada a objetos, incorporando poder de escrita com uma sintaxe clara. A linguagem foi criada em 1990 por Guido van Rossum. Site oficial: https://www.python.org/ História *1990: Criação da LP por Guido van Rossum no Stichting Mathematisch Centrum - Instituto Nacional de Pesquisa para matemática e ciência da computação. Amsterdã, Holanda *1995: Guido continua seu trabalho em Python no CRNI - Corporation for National Research Initiatives no estado de Virgínia, EUA, onde tem-se o lançamento de várias versões. *2000: Mudança de Guido e do time principal de desenvolvimento para o BeOpen.com para formar o BeOpen Python Labs *2001: Criação da Python Software Foundation (PSF), organização criada para gerenciar Propriedade Intelecual associada à linguagem Python 2 - Versões Python 3 Python 3.0 foi desenvolvida com o propósito de aprimorar alguns aspectos da linguagem, reduzindo funcionalidades redundantes. Essas mudanças não poderiam ser feitas mantendo-se a compatibilidade com versões anteriores. Algumas mudanças: *Mudanças nos objetos embutidos *Remoção de funcionalidades obsoletas *Reorganização da biblioteca principal Entre outras. Ocorreu basicamente a remoção de "velhos modos de se fazer coisas". O princípio básico era de que se deve haver um (e preferencialmente apenas um) modo de se fazer algo. As duas versões, 2.x e 3.x são mantidas pela Python Software Foundation. Python 3 - Versões Premissas de projeto Projetada para ser uma linguagem interpretada multiparadigma, podendo ser funcional, imperativa ou orientada a objetos. Segundo Guido van Rossum, motivação inicial era a criação de uma linguagem interpretada que fosse geralmente extensível. A linguagem evoluiu tornando-se de alto nível e de propósito geral, objetivando a produtividade e a manutenibilidade devido a sua alta legibilidade. Trade-offs das escolhas de projeto Prós: *Legibilidade *Capacidade de escrita *Produtividade Contras: *Relativa perda de desempenho *Distante do hardware *Necessita de execução de código para verifcação de erros básicos como erros de digitação de variáveis, ou uso de ferramentas externas para tal Domínio de aplicação *Acessibilidade *Geração de código *Computação gráfica *Configuração de hardware *Desenvolvimento multiplataforma *Banco de dados *Mineração de dados *Documentação *Email *Testes de funcionalidade *Desenvolvimento de jogos *Adminstração de sistemas *Interface gráfica *Desenvolvimento Web *E-Comércio *Controle de Qualidade *Programação científica *Ensino *etc. Usuários característicos Desenvolvimento Web *Yahoo! (Maps, Groups) *Google (Web Crawlers) *Zope Corporation (Servidor Web) Desenvolvimento de jogos *Battlefield 2 *Civilization 4 *EVE Online (MMORPG) Efeitos especiais, computação gráfica *Industrial Light & Magic *Walt Disney *Blender 3D Ciência *National Weather Service *Applied Maths *NASA Desenvolvimento de Software *Red Hat (instalador das distribuições) *Object Domain (ferramenta CASE) *SGI (Instalador Linux) *Nokia (desenvolvimento de ambiente para plataformas) Ensino *University of California (Sistemas de informação) *Delft University of Technlogy (programação cientifica aerospacial) *New Zealand Digital Library (conversor PostScript, ASCII) Entre muitos outros. Construtores da Linguagem Tipos de Dados Python trabalha com os seguintes tipos de dados: Inteiros: valores numéricos de precisão finita. float: números racionais strings: cadeia de caracteres imutável tuplas: lista com número fixo de elementos delimitados por parênteses. listas: lista mutável de elementos delimitados por colchetes. dicionário: conjunto de pares-valor associativos. Uma característica importante do Python é a utilização de tipagem dinâmica, o que significa que não é necessário declarar os tipos das variáveis para utilizá-las, pois o Python faz esta atribuição em tempo de execução. Segue um exemplo que utiliza a função type que retorna o tipo das variáveis: >>> a = 2 >>> type(a) >>> a = 7.3 >>> type(a) >>> a = "Teste" >>> type(a) >>> a = "True" >>> type(a) Strings Strings em Python são declaradas com o uso de aspas simples ou duplas. Esta estrutura de dados é imutável, o que significa que não pode ser alterada após criada. Para acessar um dos caracteres de uma string, basta acessar utilizando a sintaxe de colchetes. Segue um exemplo com a declaração de uma string e o subsequente uso de métodos e funções nesta: >>> string1 = "teste" >>> string11 'e' >>> string1.capitalize () 'Teste' >>> string1.find("te") 0 >>> string1.find("e") 0 >>> len(string1) 5 >>> print string1 teste Listas Listas podem conter elementos de diferentes tipos e são declaradas com colchetes. Uma diferença importante é que listas podem sofrer alterações em sua estrutura, podendo aumentar ou diminuir a quantidade de elementos e podendo alterar o valor dos elementos. As lista em Python também possuem uma série de funcionalidades e métodos que podem ser de grande valor na programação. >>> lista1 = 1, 2 >>> print lista1 1, 2 >>> lista1 = 'novo_elemento' >>> print lista1 'novo_elemento', 2 >>> lista2 = 5 >>> lista3 = lista1 + lista2 >>> print lista3 'novo_elemento', 2, 5 >>> print lista31:2 [ 'novo_elemento'] Tuplas Uma tupla em Python é uma estrutura de dados utilizada normalmente quando se quer guardar uma estrutura onde a ordem é relevante semanticamente. Tuplas são declaradas separando os elementos por vírgulas e são um tipo de dados imutável, ou seja, não é possível alterar a tupla após criada. Segue um exemplo: >>> data = 29, 05, "2015" >>> print data (29, 5, '2015') >>> data0 = 30 Traceback (most recent call last): File "", line1, in data0 = 30 TypeError: 'tuple' object does not support item assignment Dicionários Uma dicionário em Python é uma estrutura de dados que guarda pares chave-valor. É similar a uma lista, no sentido em que pode guardar elementos de diferentes tipos, mas a diferença é que os valores são indexados por chaves criadas pelo usuário, o que possibilita a criação de estruturas moldadas a necessidade da aplicação. >>> telefones = {'Andre': 6780001, 'Caio': 1100712} >>> telefones'Andre' 6780001 >>> telefones'Vitor' = 1223344 >>> telefones {'Andre': 6780001, 'Caio': 1100712, 'Vitor':1223344} >>> telefones.keys() 'Andre','Caio','Vitor' Palavras Reservadas False, True: resultado de operações lógicas ou de comparação None: representa a ausência de valor ou valor nulo and, or, not: operações lógicas as: utilizado para dar nomes diferentes (alias) para módulos de bibliotecas assert: utilizado para verificar o estado atual de variáveis do programa break, continue: utilizados dentro de loops para alterar o fluxo de execução class: utilizado para definir novas classes def: criação de novas funções del: utilizado para deletar referências à objetos if, elif, else, for, while: estruturas de controle de fluxo try, except, raise, finally: tratamento de exceções from, import: importar módulos/bibliotecas global: utilizado para indicar que variável dentro de uma função é global in: testa se sequência contém um valor específico is: testa se duas variáveis apontam o mesmo objeto lambda: criação de funções anônimas nonlocal: variável sendo utilizada dentro da função não é local a esta pass: utilizado quando uma função não foi implementada ainda return: retorno de valores de funções with: garante um gerenciamento adequado da estrutura (exemplo: garante que arquivo aberto seja fechado) yield: retorna um gerador (estrutura de iteração que gera valores em tempo de execução) Operadores Relacionais igualdade: a b diferente de: a != b diferente de: a <> b maior: a > b menor: a < b maior ou igual: a >= b menor ou igual: a <= b Operadores Aritméticos adição: a + b subtração: a - b multiplicação: a * b divisão: a / b resto: a % b exponencial: a ** b Operadores Lógicos a and b (Verdadeiro se ambos os operandos são verdadeiros) a or b (Verdadeiro se um dos operandos é verdadeiro) not (a and b) (inverte o estado lógico do operando) Controle de Fluxo for O comando "for" em Python difere um pouco de outras linguagens de programação. Em C, por exemplo, o programador escolhe como avança a variável de iteração (de um em um, de dois de dois, etc) e qual a condição de parada. Em Python, o "for" itera sobre os itens de uma sequência na ordem em que eles aparecem: lista1 = "b", "c" for elemento in lista1: print elemento saída: a b c if / elif / else A estrutura de controle if-else tem a seguinte forma em Python: if condicao1: comando1 elif condicao2: # elif é o equivalente de "else if" comando2 else: comando3 while A estrutura "while" tem a seguinte forma em Python: while condicao_for_atendida: faça_alguma_coisa Funções Uma função em Python é definida utilizando-se a palavra reservada "def" seguida do nome da função e parâmetros associados. Como toda estrutura definida até agora, o uso da identação é necessário para delimitar o bloco da rotina criada. Diferente de "C", em Python não se define o tipo de retorno da função explicitamente. def nome_da_funcao(param1,param2): comando1 comando2 return alguma_coisa Tratamento de Exceções A sintaxe da estrutura de tratamento de exceções em Python é bem similar à sintaxe do Java. Mas, no caso do Python utilizam-se as palavras reservadas try-except-finally. ''No exemplo a seguir, captura-se uma exceção referente à uma tentativa de divisão por zero: x = 2 y = x - 2 try: z = x / y except ZeroDivisionError as exc: print exc # irá mostrar na tela a frase "integer division or modulo by zero" finally: # os comandos desse bloco são executados independentes de exceções capturadas print "fim do bloco" '''Orientação a Objetos' Python é uma linguagem orientada a objetos, e como tal, deve dar suporte à criação de classes e métodos. Para criar uma classe, basta utilizar a palavra reservada class. ''A criação de métodos dentro de classes segue as mesmas regras de criação de funções, ou seja, utiliza a palavra reservada ''def ''seguida do nome do método e da lista de parâmetros. Segue um exemplo da criação e instanciação de uma classe em Python: class Pessoa: def __init__(self, nome): # construtor da classe self.nome = nome def getNome(self): return self.nome rafael = Pessoa ("Rafael") # instanciação da classe print rafael.nome # acessando atributo da classe instanciada (objeto) print rafael.getNome() # acessando método getNome() Avaliação da Linguagem '''Legibilidade' Não é por acaso que Python é considerada uma linguagem extremamente legível, afinal foi desenhada com isso em mente. Trata-se de uma linguagem que prioriza a legibilidade do código sobre sua velocidade de escrita ou expressividade. A identação do código não é apenas uma convenção mas sim um requerimento, um padrão, o que faz com que muitos caractéres especiais sejam dispensados, aumentando a naturalidade do código, quando comparado com um texto literário. Além de não fazer muito uso de caracteres especiais, os que estão presentes na linguagem não são muitos e também são relativamente familiares ao leitor do código: parenteses (), os parenteses retos [], chaves {}, aspas "", aspas simples , dois pontos : , vírgula , e o ponto final. . Tudo isso faz com que a linguagem seja mais amigável princípalmente para os iniciantes, que acabam tendo que enfrentar uma curva de aprendizagem menos acentuada quando comparada a linguagens mais "visualmente poluídas". Existe uma tentativa por parte dos desenvolvedores da linguagem de seguir a filosofia de ter somente uma maneira correta de se fazer algo, vide a mudança de versão 2 para a 3, embora a 2 continue sendo suportada. Existe também alguma sobrecarga de operadores, que quando não usado corretamente pode prejudicar a legibilidade. Isto é um ponto que exeplifica os motivos para os desenvolvedores se preocuparem com ter apenas uma maneira correta de se fazer algo. Vale frisar que a legibilidade facilita a manutanção do código: a preocupação princípal é com a manutenção e não com a escrita, afinal, segundo a engenharia de software, é a parte mais custosa do processo de desenvolvimento de software. '''Capacidade de escrita (Writability)' Comparações entre Python e outras lingagens geralmente espressam o quanto a linguagem pode ser simples para os olhos. Tem-se como exêmplo as seguintes porções de código equivalentes: Python: a="compare Python with Java"; print a.split(); Java: public static void main(String[] args) { String test = "compare Java with Python"; for(String a : test.split(" ")) System.out.print(a); } O suporte de Python a abstração de processos e dados tem um papel fundamental na linguagem. A grande quantidade de bibliotecas padrão implica que os programadores não precisam perder tempo para escrever códigos básicos para diversas tarefas, o que é de grande ajuda para a capacidade de escrita. Em outras palavras, os programadores não precisam implementar coisas complexas para realizar atividades simples. Um exêmplo extremamente simples seria um função de print, mas é claro que há outros exêmplos mais complexos, como as funções relacionadas a redes de computadores, aplicações para web, tratamento de listas e strings, bancos de dados, engenharia e etc. Mesmo quando não há uma biblioteca, é possível criar-se os próprios módulos que podem ser importados como as bibliotecas padrões. A modularização fica ainda mais poderosa quando considera-se que Python é uma linguagem orientada a objetos, portanto pode-se escrever classes a serem instanciadas como objetos, permitindo a re-utilização dos mesmos dispensando conhecimentos detalhados sobre suas implementações. Sua capacidade de escrita se extende, por tanto, ao domínio de negócios e domínios mixtos, sendo assim uma linguagem flexível. Além disso ela facilita o aprendizado. O poder da linguagem aumenta quando se considera que ela tem suporte para programação orientada a objetos, estruturada e recursos da programação funcional. Confiabilidade Por tratar-se de uma linguagem bem flexível, isso infere que poderiam surgir problemas relacionado a confiabilidade. Entretanto, os mesmos são evistados com o suporte natívo ao tratamento de exceções e um modelo de objetos elegante. É uma linguagem fortemente tipada e fica a cargo do programador o tratamento de tipos em funções e possui inferência de tipos, mas não realiza a conversão implícita de um tipo, exêmplo: 2+"2" TypeError: unsupported operand type(s) for +: 'int' and 'str' Por ser dinâmicamente tipada, o seguinte exêmplo é válido: dois = 2 dois = "dois" Python é uma linguagem fortemente tipada e dinâmicamente tipada ao mesmo tempo, o que a faz ser interessante nesse quesito de confiabilidade: from types import * def souInteiro (x): if type(x) IntType print "Sou inteiro." else print "Sou alguma outra coisa..." $python: souInteiro(2) Sou inteiro. $python: souInteiro("2") Sou alguma outra coisa... Como já mencionado, tem suporte nativo ao tratamento de exceções: (x, y) = (2, 0) try: z = x/y except ZeroDivisionError: print "divide by zero" É possível definir novos tipos de exceções, e isto é feito utilizando herança, onde basta a nova exceção definída herdar da classe Exception. Há também suporte para Aliasing, ou seja, objetos tem individualidade e podem estar vinculados a múltiplos nomes em diferentes escopos. Em Python, aliases funcionam quase como os ponteiros em C, permitindo ao programador passar objetos a funções para que sejam modificadas pelas funções. Custos Dado a elegância do código em Python, é de se esperar que a curva de aprendizagem não seja muito ingreme. Sendo assim os custos de aprendizagem humana são baixos quando comparados aos de outras linguagens de programação. Além do código em si, há uma enorme quantidade de recursos de aprendizagem disponíveis na literatura e uma ampla comunidade de pessoas interessadas em fórums como StackOverflow. A elegância do código em Python e a importância que os desenvolvedores deram à legibilidade do código também contribui para baixar os custos de manutenção de software escrito em Python. Vale ressaltar que isto foi priorizado, já que segundo a engenharia de software, é muito mais caro manter ou modificar um código do que escrever-lo. Quanto aos custos computacionais envolvidos, Python o código em Python não é sempre o mais otimizado pelos tradutores, que apenas fazem a tradução a um byte-code intemediário, que em seguida é interpretado. Sendo interpretada, sua velocidade de execução nem sempre é tão rápida quando linguagens compiladas como C. A vantagem que se ganha com a interpretação é a portabilidade: programas em Python podem e estão presentes em vários tipos de sistemas operacionais ou mesmo dispositívos, desde que tenham um interpretador Python compatível instalado. Projeto feito pelo grupo Astronoid A ideia inicial idealizada pelo grupo foi a de criar um simulador de gravidade, em que o personagem no simulador seria controlado pelo usuário. Cada planeta teria uma gravidade específica e com isso o comportamento do personagem seria diferenciado de acordo com o planeta que ele estava. A proposta da implementação era de mostrar de forma visual a diferença de gravidade entre os planetas. No entanto, durante o desenvolvimento do projeto a ideia tomou outro rumo: o simulador foi transformado em um jogo. O objetivo do jogo é: desviar dos meteoros que vão caindo de acordo com o quadros por segundo (a fórmula da frequência de aparição de novos meteoros depende da quantidade de quadros por segundo do jogo). A fórmula da pontuação (score) depende da quantidade de vezes que o personagem pulou e da quantidade de meteoros já desviados. Desenvolvimento O jogo foi desenvolvido utilizando a linguagem Python com a biblioteca Pygame, uma biblioteca para desenvolvimento de jogos com a linguagem Python. O Pygame é uma excelente biblioteca pelo fato de que possui várias classes e métodos prontos e próprios para o desenvolvimento de jogos tais como: efeitos sonoros, definição da tela, colisão entre sprites, etc. O código foi feito utilizando orientação a objetos e programação sequencial. As classes usadas foram: classe principal, classe para o personagem e classe para os meteoros sendo que a classe do personagem/meteoros herdam a classe principal (que inicializa o objeto, em geral, no jogo). As funções sequenciais feitas foram: uma para controlar as ações do personagem (movimentação), outra para o spawn ''dos meteoros, outra para tratar as colisões entre meteoro-personagem, uma para contabilizar a quantidade de meteoros que já foram desviados e outra para o fim do jogo (quando o personagem morre atingido por um meteoro). '''Imagens'